/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.menosehmais.framework.security;

import br.com.menosehmais.framework.security.annotation.DenyAll;
import br.com.menosehmais.framework.security.annotation.PermitAll;
import br.com.menosehmais.framework.security.annotation.RolesAllowed;
import br.com.menosehmais.framework.security.role.Role;
import java.lang.reflect.Method;

/**
 *
 * @author Rafael Quintino Gomes Rosa
 */
public class SecurityHandler {

    public static boolean canExecute(AccountInfo accountInfo, Class<?> clazz, Method method) {
        Role role = null;
        boolean isAllowed = false;

        if (accountInfo != null) {
            role = accountInfo.role();
        }

        if (method.isAnnotationPresent(DenyAll.class)) {
            return false;
        } else if (method.isAnnotationPresent(PermitAll.class)) {
            isAllowed = true;
        } else if (method.isAnnotationPresent(RolesAllowed.class)) {
            isAllowed = canExecute(role, method.getAnnotation(RolesAllowed.class).values());
        }

        if (!isAllowed) {
            if (clazz.isAnnotationPresent(DenyAll.class)) {
                return false;
            } else if (clazz.isAnnotationPresent(PermitAll.class)) {
                isAllowed = true;
            } else if (clazz.isAnnotationPresent(RolesAllowed.class)) {
                isAllowed = canExecute(role, clazz.getAnnotation(RolesAllowed.class).values());
            }
        }

        return isAllowed;
    }

    private static boolean canExecute(Role role, Class<? extends Role> roles[]) {
        if ((role == null) || (role.toString() == null) || (role.toString().length() < 1)
                || (roles == null) || (roles.length < 1)) {
            return false;
        }

        for (Class<? extends Role> allowedRole : roles) {
            if (allowedRole.isAssignableFrom(role.getClass())) {
                return true;
            }
        }

        return false;
    }
}
